{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "import sys\n",
    "sys.path.append(\"../\") \n",
    "from datetime import time\n",
    "import pandas as pd\n",
    "import pandas_market_calendars as mcal"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Calendars"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Basic Usage"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Setup new exchange calendar"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "nyse = mcal.get_calendar('NYSE')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Get the time zone"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'America/New_York'"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "nyse.tz.zone"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Get the AbstractHolidayCalendar object"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(numpy.datetime64('2200-06-19'),\n",
       " numpy.datetime64('2200-07-04'),\n",
       " numpy.datetime64('2200-09-01'),\n",
       " numpy.datetime64('2200-11-27'),\n",
       " numpy.datetime64('2200-12-25'))"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "holidays = nyse.holidays()\n",
    "holidays.holidays[-5:]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "View the available information on regular market times"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "ProtectedDict(\n",
      "{'pre': ((None, datetime.time(4, 0)),),\n",
      " 'market_open': ((None, datetime.time(10, 0)),\n",
      "                 ('1985-01-01', datetime.time(9, 30))),\n",
      " 'market_close': ((None, datetime.time(15, 0)),\n",
      "                  ('1952-09-29', datetime.time(15, 30)),\n",
      "                  ('1974-01-01', datetime.time(16, 0))),\n",
      " 'post': ((None, datetime.time(20, 0)),)}\n",
      ")\n"
     ]
    }
   ],
   "source": [
    "print(nyse.regular_market_times) # more on this under the 'Customizations' heading"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Exchange open valid business days"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Get the valid open exchange business dates between a start and end date.\n",
    "Note that Dec 26 (Christmas), Jan 2 (New Years) and all weekends are missing"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "DatetimeIndex(['2016-12-20 00:00:00+00:00', '2016-12-21 00:00:00+00:00',\n",
       "               '2016-12-22 00:00:00+00:00', '2016-12-23 00:00:00+00:00',\n",
       "               '2016-12-27 00:00:00+00:00', '2016-12-28 00:00:00+00:00',\n",
       "               '2016-12-29 00:00:00+00:00', '2016-12-30 00:00:00+00:00',\n",
       "               '2017-01-03 00:00:00+00:00', '2017-01-04 00:00:00+00:00',\n",
       "               '2017-01-05 00:00:00+00:00', '2017-01-06 00:00:00+00:00',\n",
       "               '2017-01-09 00:00:00+00:00', '2017-01-10 00:00:00+00:00'],\n",
       "              dtype='datetime64[ns, UTC]', freq=None)"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "nyse.valid_days(start_date='2016-12-20', end_date='2017-01-10')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Schedule"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>market_open</th>\n",
       "      <th>market_close</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>2016-12-30</th>\n",
       "      <td>2016-12-30 14:30:00+00:00</td>\n",
       "      <td>2016-12-30 21:00:00+00:00</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2017-01-03</th>\n",
       "      <td>2017-01-03 14:30:00+00:00</td>\n",
       "      <td>2017-01-03 21:00:00+00:00</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2017-01-04</th>\n",
       "      <td>2017-01-04 14:30:00+00:00</td>\n",
       "      <td>2017-01-04 21:00:00+00:00</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2017-01-05</th>\n",
       "      <td>2017-01-05 14:30:00+00:00</td>\n",
       "      <td>2017-01-05 21:00:00+00:00</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2017-01-06</th>\n",
       "      <td>2017-01-06 14:30:00+00:00</td>\n",
       "      <td>2017-01-06 21:00:00+00:00</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2017-01-09</th>\n",
       "      <td>2017-01-09 14:30:00+00:00</td>\n",
       "      <td>2017-01-09 21:00:00+00:00</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2017-01-10</th>\n",
       "      <td>2017-01-10 14:30:00+00:00</td>\n",
       "      <td>2017-01-10 21:00:00+00:00</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "                         market_open              market_close\n",
       "2016-12-30 2016-12-30 14:30:00+00:00 2016-12-30 21:00:00+00:00\n",
       "2017-01-03 2017-01-03 14:30:00+00:00 2017-01-03 21:00:00+00:00\n",
       "2017-01-04 2017-01-04 14:30:00+00:00 2017-01-04 21:00:00+00:00\n",
       "2017-01-05 2017-01-05 14:30:00+00:00 2017-01-05 21:00:00+00:00\n",
       "2017-01-06 2017-01-06 14:30:00+00:00 2017-01-06 21:00:00+00:00\n",
       "2017-01-09 2017-01-09 14:30:00+00:00 2017-01-09 21:00:00+00:00\n",
       "2017-01-10 2017-01-10 14:30:00+00:00 2017-01-10 21:00:00+00:00"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "schedule = nyse.schedule(start_date='2016-12-30', end_date='2017-01-10')\n",
    "schedule"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>market_open</th>\n",
       "      <th>market_close</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>2012-07-02</th>\n",
       "      <td>2012-07-02 13:30:00+00:00</td>\n",
       "      <td>2012-07-02 20:00:00+00:00</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2012-07-03</th>\n",
       "      <td>2012-07-03 13:30:00+00:00</td>\n",
       "      <td>2012-07-03 17:00:00+00:00</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2012-07-05</th>\n",
       "      <td>2012-07-05 13:30:00+00:00</td>\n",
       "      <td>2012-07-05 20:00:00+00:00</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2012-07-06</th>\n",
       "      <td>2012-07-06 13:30:00+00:00</td>\n",
       "      <td>2012-07-06 20:00:00+00:00</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2012-07-09</th>\n",
       "      <td>2012-07-09 13:30:00+00:00</td>\n",
       "      <td>2012-07-09 20:00:00+00:00</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2012-07-10</th>\n",
       "      <td>2012-07-10 13:30:00+00:00</td>\n",
       "      <td>2012-07-10 20:00:00+00:00</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "                         market_open              market_close\n",
       "2012-07-02 2012-07-02 13:30:00+00:00 2012-07-02 20:00:00+00:00\n",
       "2012-07-03 2012-07-03 13:30:00+00:00 2012-07-03 17:00:00+00:00\n",
       "2012-07-05 2012-07-05 13:30:00+00:00 2012-07-05 20:00:00+00:00\n",
       "2012-07-06 2012-07-06 13:30:00+00:00 2012-07-06 20:00:00+00:00\n",
       "2012-07-09 2012-07-09 13:30:00+00:00 2012-07-09 20:00:00+00:00\n",
       "2012-07-10 2012-07-10 13:30:00+00:00 2012-07-10 20:00:00+00:00"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# with early closes\n",
    "early = nyse.schedule(start_date='2012-07-01', end_date='2012-07-10')\n",
    "early"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>pre</th>\n",
       "      <th>market_open</th>\n",
       "      <th>market_close</th>\n",
       "      <th>post</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>2012-07-02</th>\n",
       "      <td>2012-07-02 08:00:00+00:00</td>\n",
       "      <td>2012-07-02 13:30:00+00:00</td>\n",
       "      <td>2012-07-02 20:00:00+00:00</td>\n",
       "      <td>2012-07-03 00:00:00+00:00</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2012-07-03</th>\n",
       "      <td>2012-07-03 08:00:00+00:00</td>\n",
       "      <td>2012-07-03 13:30:00+00:00</td>\n",
       "      <td>2012-07-03 17:00:00+00:00</td>\n",
       "      <td>2012-07-03 17:00:00+00:00</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2012-07-05</th>\n",
       "      <td>2012-07-05 08:00:00+00:00</td>\n",
       "      <td>2012-07-05 13:30:00+00:00</td>\n",
       "      <td>2012-07-05 20:00:00+00:00</td>\n",
       "      <td>2012-07-06 00:00:00+00:00</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2012-07-06</th>\n",
       "      <td>2012-07-06 08:00:00+00:00</td>\n",
       "      <td>2012-07-06 13:30:00+00:00</td>\n",
       "      <td>2012-07-06 20:00:00+00:00</td>\n",
       "      <td>2012-07-07 00:00:00+00:00</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2012-07-09</th>\n",
       "      <td>2012-07-09 08:00:00+00:00</td>\n",
       "      <td>2012-07-09 13:30:00+00:00</td>\n",
       "      <td>2012-07-09 20:00:00+00:00</td>\n",
       "      <td>2012-07-10 00:00:00+00:00</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2012-07-10</th>\n",
       "      <td>2012-07-10 08:00:00+00:00</td>\n",
       "      <td>2012-07-10 13:30:00+00:00</td>\n",
       "      <td>2012-07-10 20:00:00+00:00</td>\n",
       "      <td>2012-07-11 00:00:00+00:00</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "                                 pre               market_open  \\\n",
       "2012-07-02 2012-07-02 08:00:00+00:00 2012-07-02 13:30:00+00:00   \n",
       "2012-07-03 2012-07-03 08:00:00+00:00 2012-07-03 13:30:00+00:00   \n",
       "2012-07-05 2012-07-05 08:00:00+00:00 2012-07-05 13:30:00+00:00   \n",
       "2012-07-06 2012-07-06 08:00:00+00:00 2012-07-06 13:30:00+00:00   \n",
       "2012-07-09 2012-07-09 08:00:00+00:00 2012-07-09 13:30:00+00:00   \n",
       "2012-07-10 2012-07-10 08:00:00+00:00 2012-07-10 13:30:00+00:00   \n",
       "\n",
       "                        market_close                      post  \n",
       "2012-07-02 2012-07-02 20:00:00+00:00 2012-07-03 00:00:00+00:00  \n",
       "2012-07-03 2012-07-03 17:00:00+00:00 2012-07-03 17:00:00+00:00  \n",
       "2012-07-05 2012-07-05 20:00:00+00:00 2012-07-06 00:00:00+00:00  \n",
       "2012-07-06 2012-07-06 20:00:00+00:00 2012-07-07 00:00:00+00:00  \n",
       "2012-07-09 2012-07-09 20:00:00+00:00 2012-07-10 00:00:00+00:00  \n",
       "2012-07-10 2012-07-10 20:00:00+00:00 2012-07-11 00:00:00+00:00  "
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# including pre and post-market\n",
    "extended = nyse.schedule(start_date='2012-07-01', end_date='2012-07-10', start=\"pre\", end=\"post\")\n",
    "extended"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>post</th>\n",
       "      <th>market_open</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>2012-07-02</th>\n",
       "      <td>2012-07-03 00:00:00+00:00</td>\n",
       "      <td>2012-07-02 13:30:00+00:00</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2012-07-03</th>\n",
       "      <td>2012-07-04 00:00:00+00:00</td>\n",
       "      <td>2012-07-03 13:30:00+00:00</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2012-07-05</th>\n",
       "      <td>2012-07-06 00:00:00+00:00</td>\n",
       "      <td>2012-07-05 13:30:00+00:00</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2012-07-06</th>\n",
       "      <td>2012-07-07 00:00:00+00:00</td>\n",
       "      <td>2012-07-06 13:30:00+00:00</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2012-07-09</th>\n",
       "      <td>2012-07-10 00:00:00+00:00</td>\n",
       "      <td>2012-07-09 13:30:00+00:00</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2012-07-10</th>\n",
       "      <td>2012-07-11 00:00:00+00:00</td>\n",
       "      <td>2012-07-10 13:30:00+00:00</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "                                post               market_open\n",
       "2012-07-02 2012-07-03 00:00:00+00:00 2012-07-02 13:30:00+00:00\n",
       "2012-07-03 2012-07-04 00:00:00+00:00 2012-07-03 13:30:00+00:00\n",
       "2012-07-05 2012-07-06 00:00:00+00:00 2012-07-05 13:30:00+00:00\n",
       "2012-07-06 2012-07-07 00:00:00+00:00 2012-07-06 13:30:00+00:00\n",
       "2012-07-09 2012-07-10 00:00:00+00:00 2012-07-09 13:30:00+00:00\n",
       "2012-07-10 2012-07-11 00:00:00+00:00 2012-07-10 13:30:00+00:00"
      ]
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# specific market times \n",
    "# CAVEAT: Looking at 2012-07-03, you can see that times will NOT be adjusted to special_opens/sepcial_closes\n",
    "# if market_open/market_close are not requested\n",
    "specific = nyse.schedule(start_date='2012-07-01', end_date='2012-07-10', market_times= [\"post\", \"market_open\"]) # this order will be kept\n",
    "specific"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Get early closes"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>market_open</th>\n",
       "      <th>market_close</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>2012-07-03</th>\n",
       "      <td>2012-07-03 13:30:00+00:00</td>\n",
       "      <td>2012-07-03 17:00:00+00:00</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "                         market_open              market_close\n",
       "2012-07-03 2012-07-03 13:30:00+00:00 2012-07-03 17:00:00+00:00"
      ]
     },
     "execution_count": 11,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "nyse.early_closes(schedule=early)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {
    "scrolled": false
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>pre</th>\n",
       "      <th>market_open</th>\n",
       "      <th>market_close</th>\n",
       "      <th>post</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>2012-07-03</th>\n",
       "      <td>2012-07-03 08:00:00+00:00</td>\n",
       "      <td>2012-07-03 13:30:00+00:00</td>\n",
       "      <td>2012-07-03 17:00:00+00:00</td>\n",
       "      <td>2012-07-03 17:00:00+00:00</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "                                 pre               market_open  \\\n",
       "2012-07-03 2012-07-03 08:00:00+00:00 2012-07-03 13:30:00+00:00   \n",
       "\n",
       "                        market_close                      post  \n",
       "2012-07-03 2012-07-03 17:00:00+00:00 2012-07-03 17:00:00+00:00  "
      ]
     },
     "execution_count": 12,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "nyse.early_closes(schedule=extended)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Open at time\n",
    "Test to see if a given timestamp is during market open hours. (You can find more on this under the 'Advanced open_at_time' header)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "True"
      ]
     },
     "execution_count": 13,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "nyse.open_at_time(early, pd.Timestamp('2012-07-03 12:00', tz='America/New_York'))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "False"
      ]
     },
     "execution_count": 14,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "nyse.open_at_time(early, pd.Timestamp('2012-07-03 16:00', tz='America/New_York'))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Other market times will also be considered"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "True"
      ]
     },
     "execution_count": 15,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "nyse.open_at_time(extended, pd.Timestamp('2012-07-05 18:00', tz='America/New_York'))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "but can be ignored by setting only_rth = True"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "False"
      ]
     },
     "execution_count": 16,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "nyse.open_at_time(extended, pd.Timestamp('2012-07-05 18:00', tz='America/New_York'), only_rth = True)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Customizations"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The simplest way to customize the market times of a calendar is by passing datetime.time objects to the constructor, which will modify the open and/or close of *regular trading hours*."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {
    "tags": []
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "open, close: 10:00:00, 14:30:00\n"
     ]
    }
   ],
   "source": [
    "cal = mcal.get_calendar('NYSE', open_time=time(10, 0), close_time=time(14, 30))\n",
    "print('open, close: %s, %s' % (cal.open_time, cal.close_time))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "More advanced customizations can be done after initialization or by inheriting from the closest MarketCalendar class, which requires an explanation of market times..."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Market times\n",
    "Market times are moments in a trading day that are contained in the `regular_market_times` attribute, for example:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "The original NYSE calendar: \n",
      " ProtectedDict(\n",
      "{'pre': ((None, datetime.time(4, 0)),),\n",
      " 'market_open': ((None, datetime.time(10, 0)),\n",
      "                 ('1985-01-01', datetime.time(9, 30))),\n",
      " 'market_close': ((None, datetime.time(15, 0)),\n",
      "                  ('1952-09-29', datetime.time(15, 30)),\n",
      "                  ('1974-01-01', datetime.time(16, 0))),\n",
      " 'post': ((None, datetime.time(20, 0)),)}\n",
      ")\n"
     ]
    }
   ],
   "source": [
    "print(\"The original NYSE calendar: \\n\", nyse.regular_market_times)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "NYSE's regular trading hours are referenced by \"market_open\" and \"market_close\", but NYSE also has extended hours, which are referenced by \"pre\" and \"post\".\n",
    "\n",
    "*The attribute `regular_market_times` has these requirements:*\n",
    "\n",
    "* It needs to be a dictionary\n",
    "\n",
    "* Each market_time needs one entry\n",
    "    * Regular open must be \"market_open\", regular close must be \"market_close\".\n",
    "    * If there is a break, there must be a \"break_start\" and a \"break_end\".\n",
    "    * only ONE break is currently supported.\n",
    "\n",
    "\n",
    "* One tuple for each market_time, containing at least one tuple:\n",
    "\n",
    "    * Each nested tuple needs at least two items: `(first_date_used, time[, offset])`.\n",
    "    * The first tuple's date should be None, marking the start. In every tuple thereafter this is the date when `time` was first used.\n",
    "    * Optionally (assumed to be zero, when not present), a positive or negative integer, representing an offset in number of days.\n",
    "    * Dates need to be in ascending order, None coming first.\n",
    "    \n",
    "E.g.:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "((None, datetime.time(15, 0)), ('1952-09-29', datetime.time(15, 30)), ('1974-01-01', datetime.time(16, 0)))\n"
     ]
    }
   ],
   "source": [
    "print(nyse.get_time(\"market_close\", all_times= True)) # all_times = False only returns current"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The first known close was 3pm, which changed on 1952-09-29 to 3:30pm, which changed on 1974-01-01 to 4pm. The dates are the first dates that the new time was used."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Customizing after initialization\n",
    "   \n",
    "There are three methods that allow customizing the `regular_market_times` of a MarketCalendar instance:\n",
    " * `.change_time(market_time, times)`\n",
    " * `.add_time(market_time, times)`\n",
    " * `.remove_time(market_time)`"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "open, close: 10:30:00, 16:00:00\n",
      "\n",
      "The 'market_open' information is entirely replaced:\n",
      " ProtectedDict(\n",
      "{'pre': ((None, datetime.time(4, 0)),),\n",
      " 'market_open': ((None, datetime.time(10, 30)),),\n",
      " 'market_close': ((None, datetime.time(15, 0)),\n",
      "                  ('1952-09-29', datetime.time(15, 30)),\n",
      "                  ('1974-01-01', datetime.time(16, 0))),\n",
      " 'post': ((None, datetime.time(20, 0)),)}\n",
      ")\n"
     ]
    }
   ],
   "source": [
    "cal = mcal.get_calendar(\"NYSE\")\n",
    "cal.change_time(\"market_open\", time(10,30))\n",
    "print('open, close: %s, %s' % (cal.open_time, cal.close_time))\n",
    "print(\"\\nThe 'market_open' information is entirely replaced:\\n\", cal.regular_market_times)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "ProtectedDict(\n",
      "{'pre': ((None, datetime.time(4, 0)),),\n",
      " 'market_open': ((None, datetime.time(10, 30)),),\n",
      " 'market_close': ((None, datetime.time(15, 0)),\n",
      "                  ('1952-09-29', datetime.time(15, 30)),\n",
      "                  ('1974-01-01', datetime.time(16, 0))),\n",
      " 'new_post': ((None, datetime.time(19, 0)),)}\n",
      ")\n"
     ]
    }
   ],
   "source": [
    "cal.remove_time(\"post\")\n",
    "cal.add_time(\"new_post\", time(19))\n",
    "print(cal.regular_market_times)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {},
   "outputs": [],
   "source": [
    "cal.remove_time(\"pre\")\n",
    "cal.remove_time(\"new_post\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The methods `.add_time` and `.change_time` also accept the time information in these formats:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "ProtectedDict(\n",
      "{'market_open': ((None, datetime.time(10, 30)),),\n",
      " 'market_close': ((None, datetime.time(15, 0)),\n",
      "                  ('1952-09-29', datetime.time(15, 30)),\n",
      "                  ('1974-01-01', datetime.time(16, 0))),\n",
      " 'just_time': ((None, datetime.time(10, 0)),),\n",
      " 'with_offset': ((None, datetime.time(10, 0), -1),),\n",
      " 'changes_and_offset': ((None, datetime.time(17, 0)),\n",
      "                        ('2009-12-28', datetime.time(11, 0), -2))}\n",
      ")\n"
     ]
    }
   ],
   "source": [
    "cal.add_time(\"just_time\", time(10))\n",
    "cal.add_time(\"with_offset\", (time(10), -1))\n",
    "cal.add_time(\"changes_and_offset\", ((None, time(17)), (\"2009-12-28\", time(11), -2)))\n",
    "print(cal.regular_market_times)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### CAVEATS:\n",
    "\n",
    "#### FIRST\n",
    "*Internally, an order of market_times is detected based on their current time*.\\\n",
    "Because of the offsets in \"with_offset\" and \"changes_and_offset\", the columns in a schedule are in the following order:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>changes_and_offset</th>\n",
       "      <th>with_offset</th>\n",
       "      <th>just_time</th>\n",
       "      <th>market_open</th>\n",
       "      <th>market_close</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>2009-12-23</th>\n",
       "      <td>2009-12-23 22:00:00+00:00</td>\n",
       "      <td>2009-12-22 15:00:00+00:00</td>\n",
       "      <td>2009-12-23 15:00:00+00:00</td>\n",
       "      <td>2009-12-23 15:30:00+00:00</td>\n",
       "      <td>2009-12-23 21:00:00+00:00</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2009-12-24</th>\n",
       "      <td>2009-12-24 18:00:00+00:00</td>\n",
       "      <td>2009-12-23 15:00:00+00:00</td>\n",
       "      <td>2009-12-24 15:00:00+00:00</td>\n",
       "      <td>2009-12-24 15:30:00+00:00</td>\n",
       "      <td>2009-12-24 18:00:00+00:00</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2009-12-28</th>\n",
       "      <td>2009-12-26 16:00:00+00:00</td>\n",
       "      <td>2009-12-27 15:00:00+00:00</td>\n",
       "      <td>2009-12-28 15:00:00+00:00</td>\n",
       "      <td>2009-12-28 15:30:00+00:00</td>\n",
       "      <td>2009-12-28 21:00:00+00:00</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2009-12-29</th>\n",
       "      <td>2009-12-27 16:00:00+00:00</td>\n",
       "      <td>2009-12-28 15:00:00+00:00</td>\n",
       "      <td>2009-12-29 15:00:00+00:00</td>\n",
       "      <td>2009-12-29 15:30:00+00:00</td>\n",
       "      <td>2009-12-29 21:00:00+00:00</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "                  changes_and_offset               with_offset  \\\n",
       "2009-12-23 2009-12-23 22:00:00+00:00 2009-12-22 15:00:00+00:00   \n",
       "2009-12-24 2009-12-24 18:00:00+00:00 2009-12-23 15:00:00+00:00   \n",
       "2009-12-28 2009-12-26 16:00:00+00:00 2009-12-27 15:00:00+00:00   \n",
       "2009-12-29 2009-12-27 16:00:00+00:00 2009-12-28 15:00:00+00:00   \n",
       "\n",
       "                           just_time               market_open  \\\n",
       "2009-12-23 2009-12-23 15:00:00+00:00 2009-12-23 15:30:00+00:00   \n",
       "2009-12-24 2009-12-24 15:00:00+00:00 2009-12-24 15:30:00+00:00   \n",
       "2009-12-28 2009-12-28 15:00:00+00:00 2009-12-28 15:30:00+00:00   \n",
       "2009-12-29 2009-12-29 15:00:00+00:00 2009-12-29 15:30:00+00:00   \n",
       "\n",
       "                        market_close  \n",
       "2009-12-23 2009-12-23 21:00:00+00:00  \n",
       "2009-12-24 2009-12-24 18:00:00+00:00  \n",
       "2009-12-28 2009-12-28 21:00:00+00:00  \n",
       "2009-12-29 2009-12-29 21:00:00+00:00  "
      ]
     },
     "execution_count": 24,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "cal.schedule(\"2009-12-23\", \"2009-12-29\", market_times= \"all\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "On 2009-12-23 changes_and_offset doesn't seem to be in the right order, but as of 2009-12-28 it is."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Passing a list to `market_times`, allows you to keep a custom order:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>with_offset</th>\n",
       "      <th>market_open</th>\n",
       "      <th>market_close</th>\n",
       "      <th>changes_and_offset</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>2009-12-23</th>\n",
       "      <td>2009-12-22 15:00:00+00:00</td>\n",
       "      <td>2009-12-23 15:30:00+00:00</td>\n",
       "      <td>2009-12-23 21:00:00+00:00</td>\n",
       "      <td>2009-12-23 22:00:00+00:00</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2009-12-24</th>\n",
       "      <td>2009-12-23 15:00:00+00:00</td>\n",
       "      <td>2009-12-24 15:30:00+00:00</td>\n",
       "      <td>2009-12-24 18:00:00+00:00</td>\n",
       "      <td>2009-12-24 18:00:00+00:00</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2009-12-28</th>\n",
       "      <td>2009-12-27 15:00:00+00:00</td>\n",
       "      <td>2009-12-28 15:30:00+00:00</td>\n",
       "      <td>2009-12-28 21:00:00+00:00</td>\n",
       "      <td>2009-12-26 16:00:00+00:00</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2009-12-29</th>\n",
       "      <td>2009-12-28 15:00:00+00:00</td>\n",
       "      <td>2009-12-29 15:30:00+00:00</td>\n",
       "      <td>2009-12-29 21:00:00+00:00</td>\n",
       "      <td>2009-12-27 16:00:00+00:00</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "                         with_offset               market_open  \\\n",
       "2009-12-23 2009-12-22 15:00:00+00:00 2009-12-23 15:30:00+00:00   \n",
       "2009-12-24 2009-12-23 15:00:00+00:00 2009-12-24 15:30:00+00:00   \n",
       "2009-12-28 2009-12-27 15:00:00+00:00 2009-12-28 15:30:00+00:00   \n",
       "2009-12-29 2009-12-28 15:00:00+00:00 2009-12-29 15:30:00+00:00   \n",
       "\n",
       "                        market_close        changes_and_offset  \n",
       "2009-12-23 2009-12-23 21:00:00+00:00 2009-12-23 22:00:00+00:00  \n",
       "2009-12-24 2009-12-24 18:00:00+00:00 2009-12-24 18:00:00+00:00  \n",
       "2009-12-28 2009-12-28 21:00:00+00:00 2009-12-26 16:00:00+00:00  \n",
       "2009-12-29 2009-12-29 21:00:00+00:00 2009-12-27 16:00:00+00:00  "
      ]
     },
     "execution_count": 25,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "cal.schedule(\"2009-12-23\", \"2009-12-29\", market_times= [\"with_offset\", \"market_open\", \"market_close\", \"changes_and_offset\"])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### SECOND\n",
    "\n",
    "*Special closes of market_closes will override all later times, special opens of market_opens will override all earlier times*.\\\n",
    "In the prior schedule, 2009-12-24 is a special market_close, which was enforced in the changes_and_offset column.\n",
    "\n",
    "Providing `False` or `None` to the `force_special_times` keyword argument, changes this behaviour:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>changes_and_offset</th>\n",
       "      <th>market_close</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>2009-12-23</th>\n",
       "      <td>2009-12-23 22:00:00+00:00</td>\n",
       "      <td>2009-12-23 21:00:00+00:00</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2009-12-24</th>\n",
       "      <td>2009-12-24 22:00:00+00:00</td>\n",
       "      <td>2009-12-24 18:00:00+00:00</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2009-12-28</th>\n",
       "      <td>2009-12-26 16:00:00+00:00</td>\n",
       "      <td>2009-12-28 21:00:00+00:00</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "                  changes_and_offset              market_close\n",
       "2009-12-23 2009-12-23 22:00:00+00:00 2009-12-23 21:00:00+00:00\n",
       "2009-12-24 2009-12-24 22:00:00+00:00 2009-12-24 18:00:00+00:00\n",
       "2009-12-28 2009-12-26 16:00:00+00:00 2009-12-28 21:00:00+00:00"
      ]
     },
     "execution_count": 26,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# False - will only adjust the columns itself (changes_and_offset left alone, market_close adjusted)\n",
    "cal.schedule(\"2009-12-23\", \"2009-12-28\", market_times= [\"changes_and_offset\", \"market_close\"], force_special_times= False)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "metadata": {
    "scrolled": false
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>changes_and_offset</th>\n",
       "      <th>market_close</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>2009-12-23</th>\n",
       "      <td>2009-12-23 22:00:00+00:00</td>\n",
       "      <td>2009-12-23 21:00:00+00:00</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2009-12-24</th>\n",
       "      <td>2009-12-24 22:00:00+00:00</td>\n",
       "      <td>2009-12-24 21:00:00+00:00</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2009-12-28</th>\n",
       "      <td>2009-12-26 16:00:00+00:00</td>\n",
       "      <td>2009-12-28 21:00:00+00:00</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "                  changes_and_offset              market_close\n",
       "2009-12-23 2009-12-23 22:00:00+00:00 2009-12-23 21:00:00+00:00\n",
       "2009-12-24 2009-12-24 22:00:00+00:00 2009-12-24 21:00:00+00:00\n",
       "2009-12-28 2009-12-26 16:00:00+00:00 2009-12-28 21:00:00+00:00"
      ]
     },
     "execution_count": 27,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# None - will not adjust any column (both are left alone)\n",
    "cal.schedule(\"2009-12-23\", \"2009-12-28\", market_times= [\"changes_and_offset\", \"market_close\"], force_special_times= None) "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Inheriting from a MarketCalendar\n",
    "\n",
    "You get even more control over a calendar (or help this package by contributing a calendar) by inheriting from a MarketCalendar class. The following three sections cover:\n",
    "    \n",
    "    * Setting special times for market_times\n",
    "    * Setting interruptions\n",
    "    * How to make sure open_at_time works"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### Special Times\n",
    "\n",
    "Any market_time in regular_market_times can have special times, which are looked for in two properties:\n",
    "\n",
    "    special_{market_time}_adhoc\n",
    "        same format as special_opens_adhoc, which is the same as special_market_open_adhoc\n",
    "    special_{market_time}\n",
    "        same format as special_opens, which is the same as special_market_open\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "metadata": {},
   "outputs": [],
   "source": [
    "# For example, CFEExchangeCalendar only has the regular trading hours for the futures exchange (8:30 - 15:15).\n",
    "# If you want to use the equity options exchange (8:30 - 15:00), including the order acceptance time at 7:30, and\n",
    "# some special cases when the order acceptance time was different, do this:\n",
    "\n",
    "from pandas_market_calendars.exchange_calendar.cboe import CFEExchangeCalendar \n",
    "\n",
    "class DemoOptionsCalendar(CFEExchangeCalendar):  # Inherit what doesn't need to change\n",
    "    name = \"Demo_Options\"\n",
    "    aliases = [name]\n",
    "    regular_market_times = {**CFEExchangeCalendar.regular_market_times, # unpack the parent's regular_market_times\n",
    "                            \"order_acceptance\": ((None, time(7,30)),),  # add your market time of interest\n",
    "                            \"market_close\": ((None, time(15)),)} # overwrite the market time you want to change  \n",
    "    \n",
    "    @property\n",
    "    def special_order_acceptance_adhoc(self):  # include special cases\n",
    "        return [(time(8,30), [\"2000-12-27\", \"2001-12-27\"])]\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "ProtectedDict(\n",
      "{'market_open': ((None, datetime.time(8, 30)),),\n",
      " 'market_close': ((None, datetime.time(15, 0)),),\n",
      " 'order_acceptance': ((None, datetime.time(7, 30)),)}\n",
      ")\n"
     ]
    }
   ],
   "source": [
    "options = mcal.get_calendar(\"Demo_Options\")\n",
    "\n",
    "print(options.regular_market_times)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>order_acceptance</th>\n",
       "      <th>market_open</th>\n",
       "      <th>market_close</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>2000-12-22</th>\n",
       "      <td>2000-12-22 13:30:00+00:00</td>\n",
       "      <td>2000-12-22 14:30:00+00:00</td>\n",
       "      <td>2000-12-22 21:00:00+00:00</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2000-12-26</th>\n",
       "      <td>2000-12-26 13:30:00+00:00</td>\n",
       "      <td>2000-12-26 14:30:00+00:00</td>\n",
       "      <td>2000-12-26 21:00:00+00:00</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2000-12-27</th>\n",
       "      <td>2000-12-27 14:30:00+00:00</td>\n",
       "      <td>2000-12-27 14:30:00+00:00</td>\n",
       "      <td>2000-12-27 21:00:00+00:00</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2000-12-28</th>\n",
       "      <td>2000-12-28 13:30:00+00:00</td>\n",
       "      <td>2000-12-28 14:30:00+00:00</td>\n",
       "      <td>2000-12-28 21:00:00+00:00</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "                    order_acceptance               market_open  \\\n",
       "2000-12-22 2000-12-22 13:30:00+00:00 2000-12-22 14:30:00+00:00   \n",
       "2000-12-26 2000-12-26 13:30:00+00:00 2000-12-26 14:30:00+00:00   \n",
       "2000-12-27 2000-12-27 14:30:00+00:00 2000-12-27 14:30:00+00:00   \n",
       "2000-12-28 2000-12-28 13:30:00+00:00 2000-12-28 14:30:00+00:00   \n",
       "\n",
       "                        market_close  \n",
       "2000-12-22 2000-12-22 21:00:00+00:00  \n",
       "2000-12-26 2000-12-26 21:00:00+00:00  \n",
       "2000-12-27 2000-12-27 21:00:00+00:00  \n",
       "2000-12-28 2000-12-28 21:00:00+00:00  "
      ]
     },
     "execution_count": 30,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "schedule = options.schedule(\"2000-12-22\", \"2000-12-28\", start= \"order_acceptance\") \n",
    "schedule"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Dec 25th is filtered out already because it is inherited from the CFEExchangeCalendar, and the special case on 2000-12-27 is also integrated"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### Interruptions\n",
    "\n",
    "MarketCalendar subclasses also support interruptions, which can be defined in the `interruptions` property. To view interruptions, you can use the `interruptions_df` property or set `interruptions= True` when calling `schedule`."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 31,
   "metadata": {},
   "outputs": [],
   "source": [
    "class InterruptionsDemo(DemoOptionsCalendar):\n",
    "    @property\n",
    "    def interruptions(self):\n",
    "        return [\n",
    "            (\"2002-02-03\", (time(11), -1), time(11, 2)),\n",
    "            (\"2010-01-11\", time(11), (time(11, 1), 1)),\n",
    "            (\"2010-01-13\", time(9, 59), time(10), time(10, 29), time(10, 30)),\n",
    "            (\"2011-01-10\", time(11), time(11, 1))]\n",
    "    "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 32,
   "metadata": {},
   "outputs": [],
   "source": [
    "cal = InterruptionsDemo()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 33,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>interruption_start_1</th>\n",
       "      <th>interruption_end_1</th>\n",
       "      <th>interruption_start_2</th>\n",
       "      <th>interruption_end_2</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>2002-02-03</th>\n",
       "      <td>2002-02-02 17:00:00+00:00</td>\n",
       "      <td>2002-02-03 17:02:00+00:00</td>\n",
       "      <td>NaT</td>\n",
       "      <td>NaT</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2010-01-11</th>\n",
       "      <td>2010-01-11 17:00:00+00:00</td>\n",
       "      <td>2010-01-12 17:01:00+00:00</td>\n",
       "      <td>NaT</td>\n",
       "      <td>NaT</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2010-01-13</th>\n",
       "      <td>2010-01-13 15:59:00+00:00</td>\n",
       "      <td>2010-01-13 16:00:00+00:00</td>\n",
       "      <td>2010-01-13 16:29:00+00:00</td>\n",
       "      <td>2010-01-13 16:30:00+00:00</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2011-01-10</th>\n",
       "      <td>2011-01-10 17:00:00+00:00</td>\n",
       "      <td>2011-01-10 17:01:00+00:00</td>\n",
       "      <td>NaT</td>\n",
       "      <td>NaT</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "                interruption_start_1        interruption_end_1  \\\n",
       "2002-02-03 2002-02-02 17:00:00+00:00 2002-02-03 17:02:00+00:00   \n",
       "2010-01-11 2010-01-11 17:00:00+00:00 2010-01-12 17:01:00+00:00   \n",
       "2010-01-13 2010-01-13 15:59:00+00:00 2010-01-13 16:00:00+00:00   \n",
       "2011-01-10 2011-01-10 17:00:00+00:00 2011-01-10 17:01:00+00:00   \n",
       "\n",
       "                interruption_start_2        interruption_end_2  \n",
       "2002-02-03                       NaT                       NaT  \n",
       "2010-01-11                       NaT                       NaT  \n",
       "2010-01-13 2010-01-13 16:29:00+00:00 2010-01-13 16:30:00+00:00  \n",
       "2011-01-10                       NaT                       NaT  "
      ]
     },
     "execution_count": 33,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "cal.interruptions_df"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 34,
   "metadata": {
    "scrolled": false
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>market_open</th>\n",
       "      <th>market_close</th>\n",
       "      <th>interruption_start_1</th>\n",
       "      <th>interruption_end_1</th>\n",
       "      <th>interruption_start_2</th>\n",
       "      <th>interruption_end_2</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>2010-01-11</th>\n",
       "      <td>2010-01-11 14:30:00+00:00</td>\n",
       "      <td>2010-01-11 21:00:00+00:00</td>\n",
       "      <td>2010-01-11 17:00:00+00:00</td>\n",
       "      <td>2010-01-12 17:01:00+00:00</td>\n",
       "      <td>NaT</td>\n",
       "      <td>NaT</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2010-01-12</th>\n",
       "      <td>2010-01-12 14:30:00+00:00</td>\n",
       "      <td>2010-01-12 21:00:00+00:00</td>\n",
       "      <td>NaT</td>\n",
       "      <td>NaT</td>\n",
       "      <td>NaT</td>\n",
       "      <td>NaT</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2010-01-13</th>\n",
       "      <td>2010-01-13 14:30:00+00:00</td>\n",
       "      <td>2010-01-13 21:00:00+00:00</td>\n",
       "      <td>2010-01-13 15:59:00+00:00</td>\n",
       "      <td>2010-01-13 16:00:00+00:00</td>\n",
       "      <td>2010-01-13 16:29:00+00:00</td>\n",
       "      <td>2010-01-13 16:30:00+00:00</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2010-01-14</th>\n",
       "      <td>2010-01-14 14:30:00+00:00</td>\n",
       "      <td>2010-01-14 21:00:00+00:00</td>\n",
       "      <td>NaT</td>\n",
       "      <td>NaT</td>\n",
       "      <td>NaT</td>\n",
       "      <td>NaT</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2010-01-15</th>\n",
       "      <td>2010-01-15 14:30:00+00:00</td>\n",
       "      <td>2010-01-15 21:00:00+00:00</td>\n",
       "      <td>NaT</td>\n",
       "      <td>NaT</td>\n",
       "      <td>NaT</td>\n",
       "      <td>NaT</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "                         market_open              market_close  \\\n",
       "2010-01-11 2010-01-11 14:30:00+00:00 2010-01-11 21:00:00+00:00   \n",
       "2010-01-12 2010-01-12 14:30:00+00:00 2010-01-12 21:00:00+00:00   \n",
       "2010-01-13 2010-01-13 14:30:00+00:00 2010-01-13 21:00:00+00:00   \n",
       "2010-01-14 2010-01-14 14:30:00+00:00 2010-01-14 21:00:00+00:00   \n",
       "2010-01-15 2010-01-15 14:30:00+00:00 2010-01-15 21:00:00+00:00   \n",
       "\n",
       "                interruption_start_1        interruption_end_1  \\\n",
       "2010-01-11 2010-01-11 17:00:00+00:00 2010-01-12 17:01:00+00:00   \n",
       "2010-01-12                       NaT                       NaT   \n",
       "2010-01-13 2010-01-13 15:59:00+00:00 2010-01-13 16:00:00+00:00   \n",
       "2010-01-14                       NaT                       NaT   \n",
       "2010-01-15                       NaT                       NaT   \n",
       "\n",
       "                interruption_start_2        interruption_end_2  \n",
       "2010-01-11                       NaT                       NaT  \n",
       "2010-01-12                       NaT                       NaT  \n",
       "2010-01-13 2010-01-13 16:29:00+00:00 2010-01-13 16:30:00+00:00  \n",
       "2010-01-14                       NaT                       NaT  \n",
       "2010-01-15                       NaT                       NaT  "
      ]
     },
     "execution_count": 34,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "sched = cal.schedule(\"2010-01-09\", \"2010-01-15\", interruptions= True)\n",
    "sched"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 35,
   "metadata": {},
   "outputs": [],
   "source": [
    "def is_open(c, s, *dates):\n",
    "    for t in dates:\n",
    "        print(\"open on\", t, \":\", c.open_at_time(s, t))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### Advanced open_at_time\n",
    "\n",
    "`MarketCalendar.open_at_time` uses the class attribute `open_close_map` to determine if a market_time opens or closes the market. It will also look for the 'interruption_' prefix in the columns to respect interruptions."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "scrolled": true
   },
   "source": [
    "Here you can see that MarketCalendar.open_at_time respects interruptions (the last two timestamps):"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 36,
   "metadata": {
    "scrolled": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "open on 2010-01-12 14:00:00 : False\n",
      "open on 2010-01-12 14:35:00 : True\n",
      "open on 2010-01-13 15:59:00 : False\n",
      "open on 2010-01-13 16:30:00 : True\n"
     ]
    }
   ],
   "source": [
    "is_open(cal, sched, \"2010-01-12 14:00:00\", \"2010-01-12 14:35:00\",\"2010-01-13 15:59:00\",\"2010-01-13 16:30:00\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "In the `DemoOptionsCalendar`, we did not specify what order_acceptance means for the market, which will not allow open_at_time to work."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 37,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "You seem to be using a schedule that isn't based on the market_times, or includes market_times that are not represented in the open_close_map.\n"
     ]
    }
   ],
   "source": [
    "sched = cal.schedule(\"2010-01-09\", \"2010-01-15\", start= \"order_acceptance\", interruptions= True)\n",
    "try: \n",
    "    cal.open_at_time(sched, \"2010-01-12\")\n",
    "except ValueError as e: \n",
    "    print(e)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 38,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "ProtectedDict(\n",
      "{'market_open': True,\n",
      " 'market_close': False,\n",
      " 'break_start': False,\n",
      " 'break_end': True,\n",
      " 'pre': True,\n",
      " 'post': False}\n",
      ")\n"
     ]
    }
   ],
   "source": [
    "# These are the defaults that every MarketCalendar has, which is still missing order_accpetance.\n",
    "print(cal.open_close_map)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "To correct the calendar we should include the following:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 39,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>order_acceptance</th>\n",
       "      <th>market_open</th>\n",
       "      <th>market_close</th>\n",
       "      <th>interruption_start_1</th>\n",
       "      <th>interruption_end_1</th>\n",
       "      <th>interruption_start_2</th>\n",
       "      <th>interruption_end_2</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>2010-01-11</th>\n",
       "      <td>2010-01-11 13:30:00+00:00</td>\n",
       "      <td>2010-01-11 14:30:00+00:00</td>\n",
       "      <td>2010-01-11 21:00:00+00:00</td>\n",
       "      <td>2010-01-11 17:00:00+00:00</td>\n",
       "      <td>2010-01-12 17:01:00+00:00</td>\n",
       "      <td>NaT</td>\n",
       "      <td>NaT</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2010-01-12</th>\n",
       "      <td>2010-01-12 13:30:00+00:00</td>\n",
       "      <td>2010-01-12 14:30:00+00:00</td>\n",
       "      <td>2010-01-12 21:00:00+00:00</td>\n",
       "      <td>NaT</td>\n",
       "      <td>NaT</td>\n",
       "      <td>NaT</td>\n",
       "      <td>NaT</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2010-01-13</th>\n",
       "      <td>2010-01-13 13:30:00+00:00</td>\n",
       "      <td>2010-01-13 14:30:00+00:00</td>\n",
       "      <td>2010-01-13 21:00:00+00:00</td>\n",
       "      <td>2010-01-13 15:59:00+00:00</td>\n",
       "      <td>2010-01-13 16:00:00+00:00</td>\n",
       "      <td>2010-01-13 16:29:00+00:00</td>\n",
       "      <td>2010-01-13 16:30:00+00:00</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2010-01-14</th>\n",
       "      <td>2010-01-14 13:30:00+00:00</td>\n",
       "      <td>2010-01-14 14:30:00+00:00</td>\n",
       "      <td>2010-01-14 21:00:00+00:00</td>\n",
       "      <td>NaT</td>\n",
       "      <td>NaT</td>\n",
       "      <td>NaT</td>\n",
       "      <td>NaT</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2010-01-15</th>\n",
       "      <td>2010-01-15 13:30:00+00:00</td>\n",
       "      <td>2010-01-15 14:30:00+00:00</td>\n",
       "      <td>2010-01-15 21:00:00+00:00</td>\n",
       "      <td>NaT</td>\n",
       "      <td>NaT</td>\n",
       "      <td>NaT</td>\n",
       "      <td>NaT</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "                    order_acceptance               market_open  \\\n",
       "2010-01-11 2010-01-11 13:30:00+00:00 2010-01-11 14:30:00+00:00   \n",
       "2010-01-12 2010-01-12 13:30:00+00:00 2010-01-12 14:30:00+00:00   \n",
       "2010-01-13 2010-01-13 13:30:00+00:00 2010-01-13 14:30:00+00:00   \n",
       "2010-01-14 2010-01-14 13:30:00+00:00 2010-01-14 14:30:00+00:00   \n",
       "2010-01-15 2010-01-15 13:30:00+00:00 2010-01-15 14:30:00+00:00   \n",
       "\n",
       "                        market_close      interruption_start_1  \\\n",
       "2010-01-11 2010-01-11 21:00:00+00:00 2010-01-11 17:00:00+00:00   \n",
       "2010-01-12 2010-01-12 21:00:00+00:00                       NaT   \n",
       "2010-01-13 2010-01-13 21:00:00+00:00 2010-01-13 15:59:00+00:00   \n",
       "2010-01-14 2010-01-14 21:00:00+00:00                       NaT   \n",
       "2010-01-15 2010-01-15 21:00:00+00:00                       NaT   \n",
       "\n",
       "                  interruption_end_1      interruption_start_2  \\\n",
       "2010-01-11 2010-01-12 17:01:00+00:00                       NaT   \n",
       "2010-01-12                       NaT                       NaT   \n",
       "2010-01-13 2010-01-13 16:00:00+00:00 2010-01-13 16:29:00+00:00   \n",
       "2010-01-14                       NaT                       NaT   \n",
       "2010-01-15                       NaT                       NaT   \n",
       "\n",
       "                  interruption_end_2  \n",
       "2010-01-11                       NaT  \n",
       "2010-01-12                       NaT  \n",
       "2010-01-13 2010-01-13 16:30:00+00:00  \n",
       "2010-01-14                       NaT  \n",
       "2010-01-15                       NaT  "
      ]
     },
     "execution_count": 39,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "class OpenCloseDemo(InterruptionsDemo):\n",
    "    \n",
    "    open_close_map = {**CFEExchangeCalendar.open_close_map, \n",
    "                     \"order_acceptance\": True}  \n",
    "\n",
    "cal = OpenCloseDemo()\n",
    "\n",
    "sched = cal.schedule(\"2010-01-09\", \"2010-01-15\", start= \"order_acceptance\", interruptions= True)\n",
    "sched"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Now we can see that not only interruptions (last two) but also order_acceptance (first) is respected"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 40,
   "metadata": {
    "scrolled": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "open on 2010-01-11 13:35:00 : True\n",
      "open on 2010-01-12 14:35:00 : True\n",
      "open on 2010-01-13 15:59:00 : False\n",
      "open on 2010-01-13 16:30:00 : True\n"
     ]
    }
   ],
   "source": [
    "is_open(cal, sched, \"2010-01-11 13:35:00\", \"2010-01-12 14:35:00\", \"2010-01-13 15:59:00\", \"2010-01-13 16:30:00\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "You can even change this dynamically, using the `opens` keyword in `.change_time` and `.add_time`"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 41,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "open on 2010-01-11 13:35:00 : False\n",
      "open on 2010-01-12 14:35:00 : True\n",
      "open on 2010-01-13 15:59:00 : False\n",
      "open on 2010-01-13 16:30:00 : True\n"
     ]
    }
   ],
   "source": [
    "cal.change_time(\"order_acceptance\", cal[\"order_acceptance\"], opens= False)\n",
    "\n",
    "is_open(cal, sched, \"2010-01-11 13:35:00\", \"2010-01-12 14:35:00\", \"2010-01-13 15:59:00\", \"2010-01-13 16:30:00\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 42,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>order_acceptance</th>\n",
       "      <th>order_closed</th>\n",
       "      <th>market_open</th>\n",
       "      <th>market_close</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>2010-01-11</th>\n",
       "      <td>2010-01-11 13:30:00+00:00</td>\n",
       "      <td>2010-01-11 14:00:00+00:00</td>\n",
       "      <td>2010-01-11 14:30:00+00:00</td>\n",
       "      <td>2010-01-11 21:00:00+00:00</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2010-01-12</th>\n",
       "      <td>2010-01-12 13:30:00+00:00</td>\n",
       "      <td>2010-01-12 14:00:00+00:00</td>\n",
       "      <td>2010-01-12 14:30:00+00:00</td>\n",
       "      <td>2010-01-12 21:00:00+00:00</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2010-01-13</th>\n",
       "      <td>2010-01-13 13:30:00+00:00</td>\n",
       "      <td>2010-01-13 14:00:00+00:00</td>\n",
       "      <td>2010-01-13 14:30:00+00:00</td>\n",
       "      <td>2010-01-13 21:00:00+00:00</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2010-01-14</th>\n",
       "      <td>2010-01-14 13:30:00+00:00</td>\n",
       "      <td>2010-01-14 14:00:00+00:00</td>\n",
       "      <td>2010-01-14 14:30:00+00:00</td>\n",
       "      <td>2010-01-14 21:00:00+00:00</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2010-01-15</th>\n",
       "      <td>2010-01-15 13:30:00+00:00</td>\n",
       "      <td>2010-01-15 14:00:00+00:00</td>\n",
       "      <td>2010-01-15 14:30:00+00:00</td>\n",
       "      <td>2010-01-15 21:00:00+00:00</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "                    order_acceptance              order_closed  \\\n",
       "2010-01-11 2010-01-11 13:30:00+00:00 2010-01-11 14:00:00+00:00   \n",
       "2010-01-12 2010-01-12 13:30:00+00:00 2010-01-12 14:00:00+00:00   \n",
       "2010-01-13 2010-01-13 13:30:00+00:00 2010-01-13 14:00:00+00:00   \n",
       "2010-01-14 2010-01-14 13:30:00+00:00 2010-01-14 14:00:00+00:00   \n",
       "2010-01-15 2010-01-15 13:30:00+00:00 2010-01-15 14:00:00+00:00   \n",
       "\n",
       "                         market_open              market_close  \n",
       "2010-01-11 2010-01-11 14:30:00+00:00 2010-01-11 21:00:00+00:00  \n",
       "2010-01-12 2010-01-12 14:30:00+00:00 2010-01-12 21:00:00+00:00  \n",
       "2010-01-13 2010-01-13 14:30:00+00:00 2010-01-13 21:00:00+00:00  \n",
       "2010-01-14 2010-01-14 14:30:00+00:00 2010-01-14 21:00:00+00:00  \n",
       "2010-01-15 2010-01-15 14:30:00+00:00 2010-01-15 21:00:00+00:00  "
      ]
     },
     "execution_count": 42,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "cal.change_time(\"order_acceptance\", cal[\"order_acceptance\"], opens= True)\n",
    "\n",
    "cal.add_time(\"order_closed\", time(8), opens= False)\n",
    "\n",
    "sched = cal.schedule(\"2010-01-09\", \"2010-01-15\", start= \"order_acceptance\")\n",
    "sched"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 43,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "open on 2010-01-11 13:35:00 : True\n",
      "open on 2010-01-11 14:15:00 : False\n",
      "open on 2010-01-11 14:35:00 : True\n"
     ]
    }
   ],
   "source": [
    "is_open(cal, sched, \"2010-01-11 13:35:00\", \"2010-01-11 14:15:00\", \"2010-01-11 14:35:00\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Extra Usage"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Checking for special times\n",
    "*The following functions respect varying times in regular_market_times*"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "These will only check market_close/market_open columns for early/late times"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 44,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(Empty DataFrame\n",
       " Columns: [order_acceptance, market_open, market_close]\n",
       " Index: [],\n",
       " Empty DataFrame\n",
       " Columns: [order_acceptance, market_open, market_close]\n",
       " Index: [])"
      ]
     },
     "execution_count": 44,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "options.early_closes(schedule), options.late_opens(schedule)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The `is_different` method uses the name of the series passed to it, to determine which rows are not equal to the regular market times, and return a boolean Series"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 45,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>order_acceptance</th>\n",
       "      <th>market_open</th>\n",
       "      <th>market_close</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>2000-12-27</th>\n",
       "      <td>2000-12-27 14:30:00+00:00</td>\n",
       "      <td>2000-12-27 14:30:00+00:00</td>\n",
       "      <td>2000-12-27 21:00:00+00:00</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "                    order_acceptance               market_open  \\\n",
       "2000-12-27 2000-12-27 14:30:00+00:00 2000-12-27 14:30:00+00:00   \n",
       "\n",
       "                        market_close  \n",
       "2000-12-27 2000-12-27 21:00:00+00:00  "
      ]
     },
     "execution_count": 45,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "schedule[options.is_different(schedule[\"order_acceptance\"])]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "You can also pass `pd.Series.lt/ -.gt / -.ge / etc.` for more control over the comparison"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 46,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>order_acceptance</th>\n",
       "      <th>market_open</th>\n",
       "      <th>market_close</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "Empty DataFrame\n",
       "Columns: [order_acceptance, market_open, market_close]\n",
       "Index: []"
      ]
     },
     "execution_count": 46,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "schedule[options.is_different(schedule[\"order_acceptance\"], pd.Series.lt)]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 47,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>order_acceptance</th>\n",
       "      <th>market_open</th>\n",
       "      <th>market_close</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>2000-12-22</th>\n",
       "      <td>2000-12-22 13:30:00+00:00</td>\n",
       "      <td>2000-12-22 14:30:00+00:00</td>\n",
       "      <td>2000-12-22 21:00:00+00:00</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2000-12-26</th>\n",
       "      <td>2000-12-26 13:30:00+00:00</td>\n",
       "      <td>2000-12-26 14:30:00+00:00</td>\n",
       "      <td>2000-12-26 21:00:00+00:00</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2000-12-27</th>\n",
       "      <td>2000-12-27 14:30:00+00:00</td>\n",
       "      <td>2000-12-27 14:30:00+00:00</td>\n",
       "      <td>2000-12-27 21:00:00+00:00</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2000-12-28</th>\n",
       "      <td>2000-12-28 13:30:00+00:00</td>\n",
       "      <td>2000-12-28 14:30:00+00:00</td>\n",
       "      <td>2000-12-28 21:00:00+00:00</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "                    order_acceptance               market_open  \\\n",
       "2000-12-22 2000-12-22 13:30:00+00:00 2000-12-22 14:30:00+00:00   \n",
       "2000-12-26 2000-12-26 13:30:00+00:00 2000-12-26 14:30:00+00:00   \n",
       "2000-12-27 2000-12-27 14:30:00+00:00 2000-12-27 14:30:00+00:00   \n",
       "2000-12-28 2000-12-28 13:30:00+00:00 2000-12-28 14:30:00+00:00   \n",
       "\n",
       "                        market_close  \n",
       "2000-12-22 2000-12-22 21:00:00+00:00  \n",
       "2000-12-26 2000-12-26 21:00:00+00:00  \n",
       "2000-12-27 2000-12-27 21:00:00+00:00  \n",
       "2000-12-28 2000-12-28 21:00:00+00:00  "
      ]
     },
     "execution_count": 47,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "schedule[options.is_different(schedule[\"order_acceptance\"], pd.Series.ge)]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Checking custom times"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 48,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "False"
      ]
     },
     "execution_count": 48,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "options.has_custom # order_acceptance is not considered custom because it is hardcoded into the class"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 49,
   "metadata": {},
   "outputs": [],
   "source": [
    "options.add_time(\"post\", time(17))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 50,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(True, False, True)"
      ]
     },
     "execution_count": 50,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "options.has_custom, options.is_custom(\"market_open\"), options.is_custom(\"post\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Get the regular time on a certain date"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 51,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(datetime.time(9, 30, tzinfo=<DstTzInfo 'America/New_York' LMT-1 day, 19:04:00 STD>),\n",
       " datetime.time(16, 0, tzinfo=<DstTzInfo 'America/New_York' LMT-1 day, 19:04:00 STD>))"
      ]
     },
     "execution_count": 51,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "nyse.open_time, nyse.close_time  # these always refer to the current time of market_open/market_close"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 52,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(datetime.time(20, 0, tzinfo=<DstTzInfo 'America/New_York' LMT-1 day, 19:04:00 STD>),\n",
       " datetime.time(4, 0, tzinfo=<DstTzInfo 'America/New_York' LMT-1 day, 19:04:00 STD>))"
      ]
     },
     "execution_count": 52,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "nyse.get_time(\"post\"), nyse.get_time(\"pre\")  # these also refer to the current time "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 53,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(datetime.time(10, 0, tzinfo=<DstTzInfo 'America/New_York' LMT-1 day, 19:04:00 STD>),\n",
       " datetime.time(15, 30, tzinfo=<DstTzInfo 'America/New_York' LMT-1 day, 19:04:00 STD>))"
      ]
     },
     "execution_count": 53,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# open_time_on looks for market_open, close_time_on looks for market_close and get_time_on looks for the provided market time\n",
    "nyse.open_time_on(\"1950-01-01\"), nyse.get_time_on(\"market_close\", \"1960-01-01\") "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Special Methods"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 54,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "datetime.time(9, 30, tzinfo=<DstTzInfo 'America/New_York' LMT-1 day, 19:04:00 STD>)"
      ]
     },
     "execution_count": 54,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "nyse[\"market_open\"] # gets the current time"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 55,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "((None, datetime.time(10, 0)), ('1985-01-01', datetime.time(9, 30)))"
      ]
     },
     "execution_count": 55,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "nyse[\"market_open\", \"all\"] # gets all times"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 56,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "datetime.time(10, 0, tzinfo=<DstTzInfo 'America/New_York' LMT-1 day, 19:04:00 STD>)"
      ]
     },
     "execution_count": 56,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "nyse[\"market_open\", \"1950-01-01\"] # gets the time on a certain date"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "This tries to *add* a time, which will fail if it already exists. In that case `.change_time` is the explicit alternative."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 57,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "datetime.time(20, 0, tzinfo=<DstTzInfo 'America/New_York' LMT-1 day, 19:04:00 STD>)"
      ]
     },
     "execution_count": 57,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "nyse[\"new_post\"] = time(20)  \n",
    "nyse[\"new_post\"]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 58,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "post is already in regular_market_times:\n",
      "['pre', 'market_open', 'market_close', 'post', 'new_post']\n"
     ]
    }
   ],
   "source": [
    "try: nyse[\"post\"] = time(19)\n",
    "except AssertionError as e: print(e)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Array of special times"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 59,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "2000-12-27   2000-12-27 14:30:00+00:00\n",
       "2001-12-27   2001-12-27 14:30:00+00:00\n",
       "dtype: datetime64[ns, UTC]"
      ]
     },
     "execution_count": 59,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "options.special_dates(\"order_acceptance\", \"2000-12-22\", \"2001-12-28\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Handling discontinued times"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 60,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "c:\\Code\\pandas_market_calendars\\examples\\..\\pandas_market_calendars\\market_calendar.py:144: UserWarning: ['break_start', 'break_end'] are discontinued, the dictionary `.discontinued_market_times` has the dates on which these were discontinued. The times as of those dates are incorrect, use .remove_time(market_time) to ignore a market_time.\n",
      "  warnings.warn(f\"{list(discontinued.keys())} are discontinued, the dictionary\"\n"
     ]
    }
   ],
   "source": [
    "xkrx = mcal.get_calendar(\"XKRX\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 61,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>market_open</th>\n",
       "      <th>break_start</th>\n",
       "      <th>break_end</th>\n",
       "      <th>market_close</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>2020-01-02</th>\n",
       "      <td>2020-01-02 00:00:00+00:00</td>\n",
       "      <td>2020-01-02 03:00:00+00:00</td>\n",
       "      <td>2020-01-02 04:00:00+00:00</td>\n",
       "      <td>2020-01-02 06:30:00+00:00</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2020-01-03</th>\n",
       "      <td>2020-01-03 00:00:00+00:00</td>\n",
       "      <td>2020-01-03 03:00:00+00:00</td>\n",
       "      <td>2020-01-03 04:00:00+00:00</td>\n",
       "      <td>2020-01-03 06:30:00+00:00</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "                         market_open               break_start  \\\n",
       "2020-01-02 2020-01-02 00:00:00+00:00 2020-01-02 03:00:00+00:00   \n",
       "2020-01-03 2020-01-03 00:00:00+00:00 2020-01-03 03:00:00+00:00   \n",
       "\n",
       "                           break_end              market_close  \n",
       "2020-01-02 2020-01-02 04:00:00+00:00 2020-01-02 06:30:00+00:00  \n",
       "2020-01-03 2020-01-03 04:00:00+00:00 2020-01-03 06:30:00+00:00  "
      ]
     },
     "execution_count": 61,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "xkrx.schedule(\"2020-01-01\", \"2020-01-05\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 62,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "ProtectedDict({'break_start': Timestamp('2000-05-22 00:00:00'), 'break_end': Timestamp('2000-05-22 00:00:00')})"
      ]
     },
     "execution_count": 62,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "xkrx.discontinued_market_times # these are the dates as of which the market time didn't exist anymore"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 63,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "True\n",
      "False\n"
     ]
    }
   ],
   "source": [
    "print(xkrx.has_discontinued)\n",
    "xkrx.remove_time(\"break_start\")\n",
    "xkrx.remove_time(\"break_end\")\n",
    "print(xkrx.has_discontinued)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 64,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>market_open</th>\n",
       "      <th>market_close</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>2020-01-02</th>\n",
       "      <td>2020-01-02 00:00:00+00:00</td>\n",
       "      <td>2020-01-02 06:30:00+00:00</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2020-01-03</th>\n",
       "      <td>2020-01-03 00:00:00+00:00</td>\n",
       "      <td>2020-01-03 06:30:00+00:00</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "                         market_open              market_close\n",
       "2020-01-02 2020-01-02 00:00:00+00:00 2020-01-02 06:30:00+00:00\n",
       "2020-01-03 2020-01-03 00:00:00+00:00 2020-01-03 06:30:00+00:00"
      ]
     },
     "execution_count": 64,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "xkrx.schedule(\"2020-01-01\", \"2020-01-05\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Helpers\n",
    "*schedules with columns other than market_open, break_start, break_end or market_close are not yet supported by the following functions*"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Date Range\n",
    "This function will take a schedule DataFrame and return a DatetimeIndex with all timestamps at the frequency given\n",
    "for all of the exchange open dates and times."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 65,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "DatetimeIndex(['2012-07-02 20:00:00+00:00', '2012-07-03 17:00:00+00:00',\n",
       "               '2012-07-05 20:00:00+00:00', '2012-07-06 20:00:00+00:00',\n",
       "               '2012-07-09 20:00:00+00:00', '2012-07-10 20:00:00+00:00'],\n",
       "              dtype='datetime64[ns, UTC]', freq=None)"
      ]
     },
     "execution_count": 65,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "mcal.date_range(early, frequency='1D')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 66,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "DatetimeIndex(['2012-07-02 14:30:00+00:00', '2012-07-02 15:30:00+00:00',\n",
       "               '2012-07-02 16:30:00+00:00', '2012-07-02 17:30:00+00:00',\n",
       "               '2012-07-02 18:30:00+00:00', '2012-07-02 19:30:00+00:00',\n",
       "               '2012-07-02 20:00:00+00:00', '2012-07-03 14:30:00+00:00',\n",
       "               '2012-07-03 15:30:00+00:00', '2012-07-03 16:30:00+00:00',\n",
       "               '2012-07-03 17:00:00+00:00', '2012-07-05 14:30:00+00:00',\n",
       "               '2012-07-05 15:30:00+00:00', '2012-07-05 16:30:00+00:00',\n",
       "               '2012-07-05 17:30:00+00:00', '2012-07-05 18:30:00+00:00',\n",
       "               '2012-07-05 19:30:00+00:00', '2012-07-05 20:00:00+00:00',\n",
       "               '2012-07-06 14:30:00+00:00', '2012-07-06 15:30:00+00:00',\n",
       "               '2012-07-06 16:30:00+00:00', '2012-07-06 17:30:00+00:00',\n",
       "               '2012-07-06 18:30:00+00:00', '2012-07-06 19:30:00+00:00',\n",
       "               '2012-07-06 20:00:00+00:00', '2012-07-09 14:30:00+00:00',\n",
       "               '2012-07-09 15:30:00+00:00', '2012-07-09 16:30:00+00:00',\n",
       "               '2012-07-09 17:30:00+00:00', '2012-07-09 18:30:00+00:00',\n",
       "               '2012-07-09 19:30:00+00:00', '2012-07-09 20:00:00+00:00',\n",
       "               '2012-07-10 14:30:00+00:00', '2012-07-10 15:30:00+00:00',\n",
       "               '2012-07-10 16:30:00+00:00', '2012-07-10 17:30:00+00:00',\n",
       "               '2012-07-10 18:30:00+00:00', '2012-07-10 19:30:00+00:00',\n",
       "               '2012-07-10 20:00:00+00:00'],\n",
       "              dtype='datetime64[ns, UTC]', freq=None)"
      ]
     },
     "execution_count": 66,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "mcal.date_range(early, frequency='1H')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Merge schedules"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 67,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>market_open</th>\n",
       "      <th>market_close</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>2015-12-21</th>\n",
       "      <td>2015-12-21 14:30:00+00:00</td>\n",
       "      <td>2015-12-21 21:00:00+00:00</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2015-12-22</th>\n",
       "      <td>2015-12-22 14:30:00+00:00</td>\n",
       "      <td>2015-12-22 21:00:00+00:00</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2015-12-23</th>\n",
       "      <td>2015-12-23 14:30:00+00:00</td>\n",
       "      <td>2015-12-23 21:00:00+00:00</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2015-12-24</th>\n",
       "      <td>2015-12-24 14:30:00+00:00</td>\n",
       "      <td>2015-12-24 18:00:00+00:00</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2015-12-28</th>\n",
       "      <td>2015-12-28 14:30:00+00:00</td>\n",
       "      <td>2015-12-28 21:00:00+00:00</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2015-12-29</th>\n",
       "      <td>2015-12-29 14:30:00+00:00</td>\n",
       "      <td>2015-12-29 21:00:00+00:00</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2015-12-30</th>\n",
       "      <td>2015-12-30 14:30:00+00:00</td>\n",
       "      <td>2015-12-30 21:00:00+00:00</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2015-12-31</th>\n",
       "      <td>2015-12-31 14:30:00+00:00</td>\n",
       "      <td>2015-12-31 21:00:00+00:00</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2016-01-04</th>\n",
       "      <td>2016-01-04 14:30:00+00:00</td>\n",
       "      <td>2016-01-04 21:00:00+00:00</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2016-01-05</th>\n",
       "      <td>2016-01-05 14:30:00+00:00</td>\n",
       "      <td>2016-01-05 21:00:00+00:00</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2016-01-06</th>\n",
       "      <td>2016-01-06 14:30:00+00:00</td>\n",
       "      <td>2016-01-06 21:00:00+00:00</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "                         market_open              market_close\n",
       "2015-12-21 2015-12-21 14:30:00+00:00 2015-12-21 21:00:00+00:00\n",
       "2015-12-22 2015-12-22 14:30:00+00:00 2015-12-22 21:00:00+00:00\n",
       "2015-12-23 2015-12-23 14:30:00+00:00 2015-12-23 21:00:00+00:00\n",
       "2015-12-24 2015-12-24 14:30:00+00:00 2015-12-24 18:00:00+00:00\n",
       "2015-12-28 2015-12-28 14:30:00+00:00 2015-12-28 21:00:00+00:00\n",
       "2015-12-29 2015-12-29 14:30:00+00:00 2015-12-29 21:00:00+00:00\n",
       "2015-12-30 2015-12-30 14:30:00+00:00 2015-12-30 21:00:00+00:00\n",
       "2015-12-31 2015-12-31 14:30:00+00:00 2015-12-31 21:00:00+00:00\n",
       "2016-01-04 2016-01-04 14:30:00+00:00 2016-01-04 21:00:00+00:00\n",
       "2016-01-05 2016-01-05 14:30:00+00:00 2016-01-05 21:00:00+00:00\n",
       "2016-01-06 2016-01-06 14:30:00+00:00 2016-01-06 21:00:00+00:00"
      ]
     },
     "execution_count": 67,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# NYSE Calendar\n",
    "nyse = mcal.get_calendar('NYSE')\n",
    "schedule_nyse = nyse.schedule('2015-12-20', '2016-01-06')\n",
    "schedule_nyse"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 68,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>market_open</th>\n",
       "      <th>market_close</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>2015-12-21</th>\n",
       "      <td>2015-12-21 08:00:00+00:00</td>\n",
       "      <td>2015-12-21 16:30:00+00:00</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2015-12-22</th>\n",
       "      <td>2015-12-22 08:00:00+00:00</td>\n",
       "      <td>2015-12-22 16:30:00+00:00</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2015-12-23</th>\n",
       "      <td>2015-12-23 08:00:00+00:00</td>\n",
       "      <td>2015-12-23 16:30:00+00:00</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2015-12-24</th>\n",
       "      <td>2015-12-24 08:00:00+00:00</td>\n",
       "      <td>2015-12-24 12:30:00+00:00</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2015-12-29</th>\n",
       "      <td>2015-12-29 08:00:00+00:00</td>\n",
       "      <td>2015-12-29 16:30:00+00:00</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2015-12-30</th>\n",
       "      <td>2015-12-30 08:00:00+00:00</td>\n",
       "      <td>2015-12-30 16:30:00+00:00</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2015-12-31</th>\n",
       "      <td>2015-12-31 08:00:00+00:00</td>\n",
       "      <td>2015-12-31 12:30:00+00:00</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2016-01-04</th>\n",
       "      <td>2016-01-04 08:00:00+00:00</td>\n",
       "      <td>2016-01-04 16:30:00+00:00</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2016-01-05</th>\n",
       "      <td>2016-01-05 08:00:00+00:00</td>\n",
       "      <td>2016-01-05 16:30:00+00:00</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2016-01-06</th>\n",
       "      <td>2016-01-06 08:00:00+00:00</td>\n",
       "      <td>2016-01-06 16:30:00+00:00</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "                         market_open              market_close\n",
       "2015-12-21 2015-12-21 08:00:00+00:00 2015-12-21 16:30:00+00:00\n",
       "2015-12-22 2015-12-22 08:00:00+00:00 2015-12-22 16:30:00+00:00\n",
       "2015-12-23 2015-12-23 08:00:00+00:00 2015-12-23 16:30:00+00:00\n",
       "2015-12-24 2015-12-24 08:00:00+00:00 2015-12-24 12:30:00+00:00\n",
       "2015-12-29 2015-12-29 08:00:00+00:00 2015-12-29 16:30:00+00:00\n",
       "2015-12-30 2015-12-30 08:00:00+00:00 2015-12-30 16:30:00+00:00\n",
       "2015-12-31 2015-12-31 08:00:00+00:00 2015-12-31 12:30:00+00:00\n",
       "2016-01-04 2016-01-04 08:00:00+00:00 2016-01-04 16:30:00+00:00\n",
       "2016-01-05 2016-01-05 08:00:00+00:00 2016-01-05 16:30:00+00:00\n",
       "2016-01-06 2016-01-06 08:00:00+00:00 2016-01-06 16:30:00+00:00"
      ]
     },
     "execution_count": 68,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# LSE Calendar\n",
    "lse = mcal.get_calendar('LSE')\n",
    "schedule_lse = lse.schedule('2015-12-20', '2016-01-06')\n",
    "schedule_lse"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Inner merge\n",
    "This will find the dates where both the NYSE and LSE are open.\n",
    "Notice that Dec 28th is open for NYSE but not LSE.\n",
    "Also note that some days have a close prior to the open. This function does not currently check for that."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 69,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>market_open</th>\n",
       "      <th>market_close</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>2015-12-21</th>\n",
       "      <td>2015-12-21 14:30:00+00:00</td>\n",
       "      <td>2015-12-21 16:30:00+00:00</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2015-12-22</th>\n",
       "      <td>2015-12-22 14:30:00+00:00</td>\n",
       "      <td>2015-12-22 16:30:00+00:00</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2015-12-23</th>\n",
       "      <td>2015-12-23 14:30:00+00:00</td>\n",
       "      <td>2015-12-23 16:30:00+00:00</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2015-12-24</th>\n",
       "      <td>2015-12-24 14:30:00+00:00</td>\n",
       "      <td>2015-12-24 12:30:00+00:00</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2015-12-29</th>\n",
       "      <td>2015-12-29 14:30:00+00:00</td>\n",
       "      <td>2015-12-29 16:30:00+00:00</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2015-12-30</th>\n",
       "      <td>2015-12-30 14:30:00+00:00</td>\n",
       "      <td>2015-12-30 16:30:00+00:00</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2015-12-31</th>\n",
       "      <td>2015-12-31 14:30:00+00:00</td>\n",
       "      <td>2015-12-31 12:30:00+00:00</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2016-01-04</th>\n",
       "      <td>2016-01-04 14:30:00+00:00</td>\n",
       "      <td>2016-01-04 16:30:00+00:00</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2016-01-05</th>\n",
       "      <td>2016-01-05 14:30:00+00:00</td>\n",
       "      <td>2016-01-05 16:30:00+00:00</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2016-01-06</th>\n",
       "      <td>2016-01-06 14:30:00+00:00</td>\n",
       "      <td>2016-01-06 16:30:00+00:00</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "                         market_open              market_close\n",
       "2015-12-21 2015-12-21 14:30:00+00:00 2015-12-21 16:30:00+00:00\n",
       "2015-12-22 2015-12-22 14:30:00+00:00 2015-12-22 16:30:00+00:00\n",
       "2015-12-23 2015-12-23 14:30:00+00:00 2015-12-23 16:30:00+00:00\n",
       "2015-12-24 2015-12-24 14:30:00+00:00 2015-12-24 12:30:00+00:00\n",
       "2015-12-29 2015-12-29 14:30:00+00:00 2015-12-29 16:30:00+00:00\n",
       "2015-12-30 2015-12-30 14:30:00+00:00 2015-12-30 16:30:00+00:00\n",
       "2015-12-31 2015-12-31 14:30:00+00:00 2015-12-31 12:30:00+00:00\n",
       "2016-01-04 2016-01-04 14:30:00+00:00 2016-01-04 16:30:00+00:00\n",
       "2016-01-05 2016-01-05 14:30:00+00:00 2016-01-05 16:30:00+00:00\n",
       "2016-01-06 2016-01-06 14:30:00+00:00 2016-01-06 16:30:00+00:00"
      ]
     },
     "execution_count": 69,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "mcal.merge_schedules(schedules=[schedule_nyse, schedule_lse], how='inner')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Outer merge\n",
    "This will return the dates and times where either the NYSE or the LSE are open"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 70,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>market_open</th>\n",
       "      <th>market_close</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>2015-12-21</th>\n",
       "      <td>2015-12-21 08:00:00+00:00</td>\n",
       "      <td>2015-12-21 21:00:00+00:00</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2015-12-22</th>\n",
       "      <td>2015-12-22 08:00:00+00:00</td>\n",
       "      <td>2015-12-22 21:00:00+00:00</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2015-12-23</th>\n",
       "      <td>2015-12-23 08:00:00+00:00</td>\n",
       "      <td>2015-12-23 21:00:00+00:00</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2015-12-24</th>\n",
       "      <td>2015-12-24 08:00:00+00:00</td>\n",
       "      <td>2015-12-24 18:00:00+00:00</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2015-12-28</th>\n",
       "      <td>2015-12-28 14:30:00+00:00</td>\n",
       "      <td>2015-12-28 21:00:00+00:00</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2015-12-29</th>\n",
       "      <td>2015-12-29 08:00:00+00:00</td>\n",
       "      <td>2015-12-29 21:00:00+00:00</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2015-12-30</th>\n",
       "      <td>2015-12-30 08:00:00+00:00</td>\n",
       "      <td>2015-12-30 21:00:00+00:00</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2015-12-31</th>\n",
       "      <td>2015-12-31 08:00:00+00:00</td>\n",
       "      <td>2015-12-31 21:00:00+00:00</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2016-01-04</th>\n",
       "      <td>2016-01-04 08:00:00+00:00</td>\n",
       "      <td>2016-01-04 21:00:00+00:00</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2016-01-05</th>\n",
       "      <td>2016-01-05 08:00:00+00:00</td>\n",
       "      <td>2016-01-05 21:00:00+00:00</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2016-01-06</th>\n",
       "      <td>2016-01-06 08:00:00+00:00</td>\n",
       "      <td>2016-01-06 21:00:00+00:00</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "                         market_open              market_close\n",
       "2015-12-21 2015-12-21 08:00:00+00:00 2015-12-21 21:00:00+00:00\n",
       "2015-12-22 2015-12-22 08:00:00+00:00 2015-12-22 21:00:00+00:00\n",
       "2015-12-23 2015-12-23 08:00:00+00:00 2015-12-23 21:00:00+00:00\n",
       "2015-12-24 2015-12-24 08:00:00+00:00 2015-12-24 18:00:00+00:00\n",
       "2015-12-28 2015-12-28 14:30:00+00:00 2015-12-28 21:00:00+00:00\n",
       "2015-12-29 2015-12-29 08:00:00+00:00 2015-12-29 21:00:00+00:00\n",
       "2015-12-30 2015-12-30 08:00:00+00:00 2015-12-30 21:00:00+00:00\n",
       "2015-12-31 2015-12-31 08:00:00+00:00 2015-12-31 21:00:00+00:00\n",
       "2016-01-04 2016-01-04 08:00:00+00:00 2016-01-04 21:00:00+00:00\n",
       "2016-01-05 2016-01-05 08:00:00+00:00 2016-01-05 21:00:00+00:00\n",
       "2016-01-06 2016-01-06 08:00:00+00:00 2016-01-06 21:00:00+00:00"
      ]
     },
     "execution_count": 70,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "mcal.merge_schedules(schedules=[schedule_nyse, schedule_lse], how='outer')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Use holidays in numpy"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "This will use your exchange calendar in numpy to add business days"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 71,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "numpy.datetime64('2020-05-26')"
      ]
     },
     "execution_count": 71,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "import numpy as np\n",
    "cme = mcal.get_calendar(\"CME_Agriculture\")\n",
    "np.busday_offset(dates=\"2020-05-22\", holidays=cme.holidays().holidays, offsets=1)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Trading Breaks"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Some markets have breaks in the day, like the CME Equity Futures markets which are closed from 4:15 - 4:35 (NY) daily. These calendars will have additional columns in the schedule() DataFrame\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 72,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>market_open</th>\n",
       "      <th>break_start</th>\n",
       "      <th>break_end</th>\n",
       "      <th>market_close</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>2020-01-02</th>\n",
       "      <td>2020-01-01 23:00:00+00:00</td>\n",
       "      <td>2020-01-02 21:15:00+00:00</td>\n",
       "      <td>2020-01-02 21:30:00+00:00</td>\n",
       "      <td>2020-01-02 22:00:00+00:00</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2020-01-03</th>\n",
       "      <td>2020-01-02 23:00:00+00:00</td>\n",
       "      <td>2020-01-03 21:15:00+00:00</td>\n",
       "      <td>2020-01-03 21:30:00+00:00</td>\n",
       "      <td>2020-01-03 22:00:00+00:00</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "                         market_open               break_start  \\\n",
       "2020-01-02 2020-01-01 23:00:00+00:00 2020-01-02 21:15:00+00:00   \n",
       "2020-01-03 2020-01-02 23:00:00+00:00 2020-01-03 21:15:00+00:00   \n",
       "\n",
       "                           break_end              market_close  \n",
       "2020-01-02 2020-01-02 21:30:00+00:00 2020-01-02 22:00:00+00:00  \n",
       "2020-01-03 2020-01-03 21:30:00+00:00 2020-01-03 22:00:00+00:00  "
      ]
     },
     "execution_count": 72,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "cme = mcal.get_calendar('CME_Equity')\n",
    "schedule = cme.schedule('2020-01-01', '2020-01-04')\n",
    "schedule"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The date_range() properly accounts for the breaks"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 73,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "DatetimeIndex(['2020-01-02 04:00:00+00:00', '2020-01-02 09:00:00+00:00',\n",
       "               '2020-01-02 14:00:00+00:00', '2020-01-02 19:00:00+00:00',\n",
       "               '2020-01-02 21:15:00+00:00', '2020-01-02 22:00:00+00:00',\n",
       "               '2020-01-03 04:00:00+00:00', '2020-01-03 09:00:00+00:00',\n",
       "               '2020-01-03 14:00:00+00:00', '2020-01-03 19:00:00+00:00',\n",
       "               '2020-01-03 21:15:00+00:00', '2020-01-03 22:00:00+00:00'],\n",
       "              dtype='datetime64[ns, UTC]', freq=None)"
      ]
     },
     "execution_count": 73,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "mcal.date_range(schedule, '5H')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "anaconda-cloud": {},
  "kernelspec": {
   "display_name": "mcal_venv",
   "language": "python",
   "name": "mcal_venv"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.10.5"
  },
  "toc-autonumbering": true,
  "toc-showtags": false
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
